from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs, urlparse
import json
import os
from loginJudge import checkLoginInfo
import student

class RequestHandler(BaseHTTPRequestHandler):
    """增强版请求处理器"""
    
    def _set_headers(self, status=200, content_type='text/html'):
        """统一设置响应头（增加编码声明）"""
        self.send_response(status)
        self.send_header('Content-type', content_type)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
    
    def do_OPTIONS(self):
        """处理预检请求"""
        self._set_headers()#调用上面的函数设置请求头
        self.end_headers()#请求头与请求体之间应该有一个空行，这行语句增加一个空行
    
    def do_GET(self):
        """处理所有GET请求"""
        # 路由配置
        if self.path=="/":#当访问路径为根路径时，读取login.html返给前端
            self._serve_static(r'./pages/login.html')
        elif self.path == '/success':#当访问路径为/success时，读取login_success.html返给前端
            self._serve_static(r'./pages/login_success.html')
        elif self.path=='/stuManage':
            self._serve_static(r'./pages/stuManage.html')
        elif self.path=="/api/getAllStudents":#获取所有学生信息
            self._handel_getAllStudents()
        else:#当访问路径没有定义时，读取login.html返给前端
            self._serve_static(r'./pages/login.html')
    
    def do_POST(self):
        """处理POST请求"""
        if self.path == '/login':#提供/login接口，处理登录请求
            self._handle_login()
        elif self.path == '/api/getStudentsByClass':#获取班级所有学生信息
            self._handle_getStudentsByClass()
        elif self.path == '/api/getStudentsLikeNameOrStuid':#通过姓名或者智学号查找学生
            self._handle_getStudentsLikeNameOrStuid()
        elif self.path == '/api/addStudent':#添加学生
            self._handle_addStudent()
        elif self.path == '/api/deleteStudent':#删除学生
            self._handle_deleteStudent()
        elif self.path == '/api/editStudent':#比纳基学生信息
            self._handle_editStudent()
        else:#其他接口直接404
            self.send_error(404, "Not Found")
    
    def _serve_static(self, filename):#读取静态页面文件并返给前端
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                self._set_headers(content_type='text/html; charset=utf-8')
                self.end_headers()
                self.wfile.write(f.read().encode('utf-8'))
        except FileNotFoundError:
            self.send_error(404, "File Not Found") 

    def _serve_static_replace(self, filename,content):#读取静态页面文件，替换掉其中的占位符后返给前端
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                html=f.read()
                html=html.replace("$$$",content)
                self._set_headers(content_type='text/html; charset=utf-8')
                self.end_headers()
                self.wfile.write(html.encode('utf-8'))
        except FileNotFoundError:
            self.send_error(404, "File Not Found") 

    
    def _handle_login(self):
        """处理登录逻辑"""
        loginStyle=True#登陆方式，如果是通过表单的自带的submit登陆的置为True,如果是通过js 的ajax请求登陆的置为False
        try:
            content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
            post_data = self.rfile.read(content_length)#读取请求体数据
            content_type = self.headers.get('Content-Type', '')#获取请求体数据格式
            
            if 'application/x-www-form-urlencoded' in content_type:#处理表单中的action请求，格式为application/x-www-form-urlencoded
                loginStyle=True
                data = parse_qs(post_data.decode())
                username = data['username'][0]
                password = data['password'][0]
            elif 'application/json' in content_type:#处理通过js发送过来的json格式数据
                loginStyle=False
                data = json.loads(post_data.decode())
                username = data['username']
                password = data['password']
            else:#其他格式不支持
                self.send_error(400, 'Unsupported Content-Type')
                return

            response=checkLoginInfo(username,password) #判断登录信息是否正确，此函数留给学生实现  

            if loginStyle:
                if response["success"]:
                    self.send_response(302)
                    self.send_header('Location', '/stuManage')
                    self.end_headers()
                    #self._serve_static(r'./pages/stuManage.html')
                else:
                    self._serve_static_replace(r'./pages/login_failed.html',response["message"])
            else:        
                if response["success"]:#根据返回的success键值对判断登录是否成功，返回对应的状态码
                    self.send_response(302)
                    self.send_header('Location', '/stuManage')
                    self.end_headers()
                else:
                    status=401
                    # 调用上面定义的函数发送响应
                    self._set_headers(status, content_type='application/json')#组织响应头
                    self.end_headers()#加入空行
                    self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端
            
        except Exception as e:
            self.send_error(400, f"无效请求: {str(e)}")

    def _handel_getAllStudents(self):
        response=student.getAllStudents()
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

    def _handle_getStudentsByClass(self):
        content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
        post_data = self.rfile.read(content_length)#读取请求体数据
        data = json.loads(post_data.decode())
        classid = data['classid']
        response=student.getStudentsByClass(classid)
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

    def _handle_getStudentsLikeNameOrStuid(self):
        content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
        post_data = self.rfile.read(content_length)#读取请求体数据
        data = json.loads(post_data.decode())
        nameOrStuid = data['nameOrStuid']
        response=student.getStudentsLikeNameOrStuid(nameOrStuid)
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

    def _handle_addStudent(self):
        content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
        post_data = self.rfile.read(content_length)#读取请求体数据
        studentData = json.loads(post_data.decode())
        response = student.addStudent(studentData["studentData"])
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

    def _handle_deleteStudent(self):
        content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
        post_data = self.rfile.read(content_length)#读取请求体数据
        id = json.loads(post_data.decode())
        try:
            student.deleteStudent(int(id["id"]))
            response={"ok":True}
        except:
            response={"ok":False}
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

    def _handle_editStudent(self):
        content_length = int(self.headers.get('Content-Length', 0))#获取请求数据长度
        post_data = self.rfile.read(content_length)#读取请求体数据
        studentData = json.loads(post_data.decode())
        #try:            
        student.editStudent(studentData["studentData"])
        response={"ok":True}
        #except:
        #    response={"ok":False}
        self._set_headers(content_type='application/json')#组织响应头
        self.end_headers()#加入空行
        self.wfile.write(json.dumps(response).encode('utf-8'))#将返回的信息已json格式组织，并以utf-8编码发送给前端

if __name__ == '__main__':
    port = 5000
    server = HTTPServer(('0.0.0.0', port), RequestHandler)
    print(f"服务已启动：http://0.0.0.0:{port}")
    server.serve_forever()